home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Die Speccy' 97
/
Die Speccy' 97.iso
/
amiga_system
/
the_aminet
/
util
/
libs
/
halt.lzh
/
halt
/
halt_library.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-10-06
|
5KB
|
235 lines
/*
halt_library.c --- halt library interface.
(c) Copyright 1995 SHW Wabnitz
Written by Bernhard Fastenrath (fasten@shw.com)
This file may be distributed under the terms
of the GNU General Public License.
*/
#if defined (__GNUC__)
#include <stabs.h>
#endif
#include "halt_library.h"
struct ExecBase *SysBase = NULL;
struct DosLibrary *DOSBase = NULL;
struct Library *HaltBase = NULL;
struct List Clients;
ULONG ClientsListBusy = 0;
#if defined (__GNUC__)
const BYTE LibName[] = "halt.library";
const BYTE LibIdString[] = "$VER: halt.library 2.0 (10-6-95)";
const UWORD LibVersion = 2;
const UWORD LibRevision = 0;
#endif
#if defined (__GNUC__)
#define LIBRT
#define REG_a6
#define REG_d1
#define STRUCT_MYLIB struct Library
#else
#define LIBRT __saveds __asm
#define REG_a6 register __a6
#define REG_d1 register __d1
#define ADDTABL_1(name,arg1);
#define ADDTABL_END();
#define STRUCT_MYLIB struct MyLibrary
#endif
static void
cleanup (void)
{
if (DOSBase)
CloseLibrary ((struct Library *) DOSBase);
DOSBase = NULL;
}
int LIBRT
__UserLibInit (REG_a6 STRUCT_MYLIB *libbase)
{
SysBase = *(struct ExecBase **)4;
HaltBase = (struct Library *) libbase;
if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
return 1;
NewList (&Clients);
return 0; /* success */
}
void LIBRT
__UserLibCleanup (REG_a6 STRUCT_MYLIB *libbase)
{
cleanup ();
}
ADDTABL_1(LIBReboot,d1);
int LIBRT
LIBReboot (REG_d1 int flags)
{
if (flags)
{
Disable ();
while (1);
}
ColdReboot ();
return 1;
}
ADDTABL_1(LIBUnmount,d1);
int LIBRT
LIBUnmount (REG_d1 char *filesystem)
{
return unmount (NULL, filesystem);
}
ADDTABL_1(LIBAddShutdownPort,d1);
int LIBRT
LIBAddShutdownPort (REG_d1 MsgPort *prt)
{
ShutdownClient *scl;
if (((struct Process *) prt -> mp_SigTask) -> pr_WindowPtr != (void *) -1)
return 0;
if (!(scl = (ShutdownClient *) AllocMem (sizeof (ShutdownClient), MEMF_PUBLIC)))
return 0;
scl -> port = prt;
scl -> done = 0;
Forbid ();
AddHead (&Clients, (Node *) scl);
Permit ();
return 1;
}
ADDTABL_1(LIBRemShutdownPort,d1);
int LIBRT
LIBRemShutdownPort (REG_d1 MsgPort *prt)
{
MinNode *mln;
int ret = 0;
Forbid ();
for (mln = (MinNode *) Clients.lh_Head; mln -> mln_Succ; mln = mln -> mln_Succ)
if (((ShutdownClient *) mln) -> port == prt)
{
if (ClientsListBusy)
((ShutdownClient *) mln) -> done = 1;
else
{
Remove ((Node *) mln);
FreeMem (mln, sizeof (ShutdownClient));
}
ret = 1;
break;
}
Permit ();
return ret;
}
ADDTABL_1(LIBShutdownStatus,d1);
int LIBRT
LIBShutdownStatus (REG_d1 ShutdownMessage *smsg)
{
ShutdownClient *scl, *next;
ULONG abortable = 0;
MsgPort *prt;
Task *me;
ULONG mp_mask, mask, rmask;
smsg -> sm_Context -> sc_rMask = 0;
smsg -> sm_Context -> sc_Port = NULL;
if (IsListEmpty (&Clients))
return 1;
me = FindTask (0);
prt = smsg -> sm_Msg.mn_ReplyPort;
if (smsg -> sm_Status != SHUTDOWN_HALT &&
smsg -> sm_Status != SHUTDOWN_ABORT &&
smsg -> sm_Status != SHUTDOWN_UMOUNT)
{
abortable = smsg -> sm_Flags & SDMF_ABORTABLE;
}
Forbid ();
ClientsListBusy ++;
Permit ();
mp_mask = 1 << prt -> mp_SigBit;
mask = mp_mask | SIGBREAKF_CTRL_C | smsg -> sm_Context -> sc_Mask;
scl = (ShutdownClient *) Clients.lh_Head;
while (next = (ShutdownClient *) scl -> node.mln_Succ)
{
if (scl -> done)
{
Forbid ();
if (ClientsListBusy == 1)
{
Remove ((Node *) scl);
FreeMem (scl, sizeof (ShutdownClient));
}
Permit ();
}
else
{
if (scl -> port -> mp_SigTask != me)
{
PutMsg (scl -> port, (Message *) smsg);
for (;;)
{
if ((rmask = Wait (mask)) & mp_mask)
{
if (GetMsg (prt) == (Message *) smsg)
break;
else
smsg -> sm_Context -> sc_TimeOuts --;
}
if (rmask & SIGBREAKF_CTRL_C)
{
smsg -> sm_Flags |= (SDMF_CANCEL | SDMF_CTRL_C);
smsg -> sm_Context -> sc_Port = scl -> port;
smsg -> sm_Context -> sc_TimeOuts ++;
break;
}
if (rmask & smsg -> sm_Context -> sc_Mask)
{
/* Usually this is a timeout so we put the nasty
program at the end of the list.
*/
Remove ((Node *) scl);
AddTail (&Clients, (Node *) scl);
smsg -> sm_Flags |= SDMF_SIG_MASK;
smsg -> sm_Context -> sc_Port = scl -> port;
smsg -> sm_Context -> sc_TimeOuts ++;
break;
}
}
if (abortable && smsg -> sm_Flags & (SDMF_CANCEL | SDMF_SIG_MASK))
break;
}
}
scl = next;
}
smsg -> sm_Context -> sc_rMask = rmask;
if (!abortable)
smsg -> sm_Flags &= ~(SDMF_CANCEL | SDMF_CTRL_C);
Forbid ();
ClientsListBusy --;
Permit ();
return 1;
}
ADDTABL_END();